package ro.msg.quiz.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import ro.msg.quiz.domain.MultipleChoiceQuestion;
import ro.msg.quiz.domain.Question;
import ro.msg.quiz.domain.QuestionType;
import ro.msg.quiz.domain.SingleChoiceQuestion;
import ro.msg.quiz.domain.TextQuestion;
import ro.msg.quiz.exception.MyException;
import ro.msg.quiz.repository.Repository;
import ro.msg.quiz.validator.IValidator;
import ro.msg.quiz.validator.MultipleChoiceQuestionValidator;
import ro.msg.quiz.validator.SingleChoiceQuestionValidator;
import ro.msg.quiz.validator.TextQuestionValidator;

//AUTHORS: Elod, Razvan

//Class responsible for adding, deleting and updating a valid question in the list of questions from repository 
public class QuestionService implements IService<Question> {
    Repository repo = Repository.getInstance();
    IValidator<Question> validator;

    // adds a valid question in the list of questions from repository
    @Override
    public void add(Question t) throws MyException {
	if (exists(t))
	    throw new MyException("The question already exists!");
	int newId = idGenerator();
	t.setId(newId);
	if (t.getType().equals(QuestionType.SINGLE_CHOICE_Q)) {
	    validator = new SingleChoiceQuestionValidator();
	    validator.validate(t);
	} else if (t.getType().equals(QuestionType.MULTIPLE_CHOICE_Q)) {
	    validator = new MultipleChoiceQuestionValidator();
	    validator.validate(t);
	} else if (t.getType().equals(QuestionType.TEXT_Q)) {
	    validator = new TextQuestionValidator();
	    validator.validate(t);
	}
	repo.getQuestionsList().add(t);
    }

    // deletes a question from the list of questions from repository
    // if the question is not found by it's text than an exception is thrown
    @Override
    public void delete(String textQuestion) throws MyException {
	for (Question q : this.repo.getQuestionsList()) {
	    if (q.getText().equals(textQuestion)) {
		repo.getQuestionsList().remove(q);
		return;
	    }
	}
	throw new MyException("The question does not exist!");
    }

    // updates a question in the list of questions from repository
    // if the question exists in repository
    @Override
    public void update(Question t) throws MyException {
	if (!existsById(t.getId()))
	    throw new MyException("The question does not exist!");
	List<Question> newList = Collections.synchronizedList(new ArrayList<Question>());
	newList = repo.getQuestionsList();
	int k = -1;
	for (k = 0; k < newList.size(); k++) {
	    Question q = newList.get(k);
	    if (q.getId() == t.getId()) {
		newList.remove(k);
		t.setText(q.getText());
		if (t instanceof SingleChoiceQuestion) {
		    validator = new SingleChoiceQuestionValidator();
		    validator.validate(t);
		} else if (t instanceof MultipleChoiceQuestion) {
		    validator = new MultipleChoiceQuestionValidator();
		    validator.validate(t);
		} else if (t instanceof TextQuestion) {
		    validator = new TextQuestionValidator();
		    validator.validate(t);
		}
		newList.add(t);
	    }

	}
	repo.setQuestionList(newList);
    }

    // verifies if a question appears in repository
    @Override
    public boolean exists(Question t) {
	return repo.getQuestionsList().contains(t);
    }

    // generates a new id for a question, by incrementing the maximum value of
    // id
    // from the list of questions in repository
    @Override
    public int idGenerator() {
	int max = 0;
	for (Question q : repo.getQuestionsList()) {
	    if (q.getId() > max) {
		max = q.getId();
	    }
	}
	max++;
	return max;
    }

    // verifies if a question appears in repository
    public boolean existsById(int id) {
	for (Question q : repo.getQuestionsList()) {
	    if (q.getId() == id)
		return true;
	}
	return false;
    }

}